package com.wangsd.web.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.util.SignUtils;
import com.wangsd.common.basicbean.MyController;
import com.wangsd.common.utils.BaseUtils;
import com.wangsd.web.api.service.NotifyService;
import com.wangsd.web.shop.entity.Coupon;
import com.wangsd.web.shop.entity.CouponOrder;
import com.wangsd.web.shop.entity.Member;
import com.wangsd.web.shop.entity.Trade;
import com.wangsd.web.shop.service.CouponOrderService;
import com.wangsd.web.shop.service.CouponService;
import com.wangsd.web.shop.service.MemberService;
import com.wangsd.web.shop.service.TradeService;
import com.wangsd.web.sys.entity.SysCompany;
import com.wangsd.web.sys.service.SysCompanyService;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Api(tags = "接口管理")
@RestController
@RequestMapping("/api/notify")
@Slf4j
public class NotifyController extends MyController {

    @Autowired
    private NotifyService notifyService;
    @Autowired
    private TradeService tradeService;
    @Autowired
    private SysCompanyService companyService;
    @Autowired
    MemberService memberService;
    @Autowired
    CouponService couponService;
    @Autowired
    CouponOrderService couponOrderService;

    /**
     * test
     * 测试回调
     */
    @RequestMapping("/testNotify")
    public String testNotify(@RequestBody Map request) {
        log.info(JSON.toJSONString(request));
        return "success";
    }

    /**
     * 微信支付回调
     * @param requestBody
     * @return
     */
    @RequestMapping("/wxPayBack")
    public String wxPayBack(@RequestBody String requestBody) {
        String returnXml = "<xml>"
                + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>"
                + "</xml> ";
        log.debug("微信支付回调报文==" + requestBody);
        Map<String, String> map = BaseUtils.doXMLParse(requestBody);
        String returnCode = map.get("return_code");
        String resultCode = map.get("result_code");

        if (WxPayConstants.ResultCode.SUCCESS.equals(returnCode)//执行结果成功
                && WxPayConstants.ResultCode.SUCCESS.equals(resultCode)) {//业务结果成功
            String outTradeNo = map.get("out_trade_no");
            String transactionId = map.get("transaction_id");
            int totalFee = Integer.parseInt(map.get("total_fee").toString());
            String wxSign = map.get("sign");
            String mchId = map.get("mch_id");
            String time_end = map.get("time_end");
            String sub_mch_id = map.get("sub_mch_id");
            Integer cash_fee = Integer.parseInt(map.get("cash_fee"));
            Integer settlement_total_fee = cash_fee;
            if (map.get("settlement_total_fee") != null) {
                settlement_total_fee = Integer.parseInt(map.get("settlement_total_fee"));
            }
            Integer coupon_fee = 0;
            if (map.get("coupon_fee") != null) {
                coupon_fee = Integer.parseInt(map.get("coupon_fee"));
            }
            //查询购买的优惠券
//            CouponOrder couponOrder = couponOrderService.selectByOutTradeNo(outTradeNo);
//            if (couponOrder != null) {
//                SysCompany company = companyService.selectByWxMchId(mchId);
//                String mySign = SignUtils.createSign(map, "MD5", company.getWxMchKey(), new String[0]);
//                if (wxSign.equals(mySign) && totalFee == couponOrder.getPrice()) {//签名验证成功
//                    Coupon coupon = couponService.selectByStockId(couponOrder.getStockId());
//                    Member member = memberService.selectByMiniOpenId(couponOrder.getMiniOpenid());
//                    couponService.sendCoupon2(coupon, member, couponOrder.getId());
//                }
//            }
            Trade trade = tradeService.selectByOutTradeNo(outTradeNo);
            if (trade == null) {
                trade = tradeService.selectByOutTradeNoDelete(outTradeNo);
            }
            if (trade != null) {
                SysCompany company = companyService.selectByWxMchId(mchId);
                String mySign = SignUtils.createSign(map, "MD5", company.getWxMchKey(), new String[0]);
                if (wxSign.equals(mySign) && totalFee == trade.getPrice()) {//签名验证成功
                    trade.setCashFee(cash_fee);
                    trade.setSettlementTotalFee(settlement_total_fee);
                    trade.setCouponFee(coupon_fee);
                    trade.setStatus(1);
                    trade.setTransactionId(transactionId);
                    trade.setPayTime(time_end);
                    trade.setSubMchId(sub_mch_id);
                    trade.setIsDeleted(false);

                    Coupon coupon = couponService.selectByStockId(trade.getProductNo());
                    if (coupon.getStockType().equals("NORMAL")) {
                        Member member = memberService.selectByMiniOpenId(trade.getMiniOpenid());
                        couponService.sendCoupon2(coupon, member, null);
                        trade.setSendStatus(2);
                    }
                    tradeService.save(trade);
                }
            }

        }
        return returnXml;
    }


    @RequestMapping("/webOpenid")
    public String webOpenid(String appid, String code, String state, String openid) {
        log.debug("网页授权回调通知：appid={},code={},state={},openid={}", appid, code, state, openid);
        Member member = (Member) redisTemplate.opsForValue().get(state);
        member.setPayOpenid(openid);
        redisTemplate.opsForValue().set(state, member, 3, TimeUnit.HOURS);
        memberService.updatePayOpenid(member.getMiniOpenid(), openid);
        return "success";
    }


    @PostMapping("/{companyId}/coupon")
    public Object coupon(@RequestBody String body, @PathVariable Long companyId) {
        log.debug("代金券核销回调==" + body);
        JSONObject obj = JSON.parseObject(body).getJSONObject("resource");
        String event_type = JSON.parseObject(body).getString("event_type");

        String associated_data = obj.getString("associated_data");
        String nonce = obj.getString("nonce");
        String ciphertext = obj.getString("ciphertext");
        try {
            SysCompany company = companyService.selectById(companyId);
            AesUtil decryptor = new AesUtil(company.getWxApiV3Key().getBytes("utf-8"));
            String str = decryptor.decryptToString(associated_data.replaceAll("\"", "").getBytes(),
                    nonce.replaceAll("\"", "").getBytes(),
                    ciphertext.replaceAll("\"", ""));
            log.debug("代金券核销回调解密后==" + str);
            //代金券核销通知
            if (event_type.equals("COUPON.USE")) {
                couponService.consumeCoupon(str);
            }
            //商家券领取通知
            if (event_type.equals("COUPON.SEND")) {
                JSONObject json = JSON.parseObject(str);
                couponService.sendCouponSuccess(json.getString("send_req_no"), json.getString("coupon_code"));
                /**
                 * {
                 *     "event_type": "EVENT_TYPE_BUSICOUPON_SEND",
                 *     "coupon_code": "1200950231000041840162",
                 *     "stock_id": "1226950000000007",
                 *     "send_time": "2020-06-04T10:34:40+08:00",
                 *     "openid": "oEgED5VK0bNge_UXl5pSqBrw31L4",
                 *     "unionid": "",
                 *     "send_channel": "BUSICOUPON_SEND_CHANNEL_MINIAPP",
                 *     "send_merchant": "1557191411",
                 *     "attach_info": "",
                 *     "send_req_no": "1591238065627"
                 * }
                 */
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map map = new HashMap();
        map.put("code", "SUCCESS");
        map.put("message", "SUCCESS");
        return map;
    }
}
